<html>
<head><meta charset="utf-8"><title>repr(transparent) · t-lang/wg-unsafe-code-guidelines · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/index.html">t-lang/wg-unsafe-code-guidelines</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html">repr(transparent)</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="194020565"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28transparent%29/near/194020565" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html#194020565">(Apr 15 2020 at 12:20)</a>:</h4>
<p>Hi, I was sure that <code>repr(transparent)</code> allowed <code>transmute&lt;&amp;Wrapper, &amp;Inner&gt;(...)</code> or <code>*const Wrapper as *Const Inner</code>.</p>
<p>But going over <code>UnsafeCell</code> impl I've found this: <a href="https://doc.rust-lang.org/src/core/cell.rs.html#1543" title="https://doc.rust-lang.org/src/core/cell.rs.html#1543">https://doc.rust-lang.org/src/core/cell.rs.html#1543</a></p>
<blockquote>
<div class="codehilite"><pre><span></span>    // We can just cast the pointer from `UnsafeCell&lt;T&gt;` to `T` because of
    // #[repr(transparent)]. This exploits libstd&#39;s special status, there is
    // no guarantee for user code that this will work in future versions of the compiler!
</pre></div>


</blockquote>
<p>Does this mean that repr(transparent) doesn't work that way for everyone?</p>



<a name="194021445"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28transparent%29/near/194021445" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html#194021445">(Apr 15 2020 at 12:27)</a>:</h4>
<p>I <em>think</em> that might be because repr(transparent) on UnsafeCell isn't stabilized for end-users, or at least I see no mention in the docs</p>



<a name="194037594"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28transparent%29/near/194037594" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html#194037594">(Apr 15 2020 at 14:20)</a>:</h4>
<p>This part of the comment was added in <a href="https://github.com/rust-lang/rust/pull/66248" title="https://github.com/rust-lang/rust/pull/66248">https://github.com/rust-lang/rust/pull/66248</a> for reasons discussed there, seems more related to what we document about <code>UnsafeCell</code> (treat <code>get</code> as being special) than repr(transparent) in particular.</p>



<a name="194038358"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28transparent%29/near/194038358" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html#194038358">(Apr 15 2020 at 14:25)</a>:</h4>
<p>However, there <em>are</em> significant caveats to "repr(transparent) allows type punning via pointer casts" -- e.g. transparent wrappers do not necessarily have the same safety and validity invariants as the type they wrap. Such issues can be ruled out if you control both types or the types provide sufficient documented guarantees, but libstd types don't usually give that many guarantees.</p>



<a name="194368152"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28transparent%29/near/194368152" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html#194368152">(Apr 16 2020 at 21:12)</a>:</h4>
<p>Indeed the main reason for that comment is the special status of <code>UnsafeCell::get</code>. That is the only way to get an interior mutable pointer. This trumps <code>repr(transparent)</code>.</p>



<a name="194368850"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28transparent%29/near/194368850" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html#194368850">(Apr 16 2020 at 21:19)</a>:</h4>
<p>ah, so transmuting <code>&amp;mut UnsafeCell&lt;T&gt;</code> to <code>*mut T</code> wouldn't also do it? Interesting. If so, is that written down somewhere?</p>



<a name="194368929"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28transparent%29/near/194368929" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html#194368929">(Apr 16 2020 at 21:20)</a>:</h4>
<p>(i mean somewhere outside of that one code comment on the unsafecell impl)</p>



<a name="194369510"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28transparent%29/near/194369510" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html#194369510">(Apr 16 2020 at 21:25)</a>:</h4>
<p><span class="user-mention silent" data-user-id="224471">Lokathor</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/repr(transparent)/near/194368850" title="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/repr(transparent)/near/194368850">said</a>:</p>
<blockquote>
<p>ah, so transmuting <code>&amp;mut UnsafeCell&lt;T&gt;</code> to <code>*mut T</code> wouldn't also do it? Interesting. If so, is that written down somewhere?</p>
</blockquote>
<p>wait no that is no problem</p>



<a name="194369522"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28transparent%29/near/194369522" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html#194369522">(Apr 16 2020 at 21:25)</a>:</h4>
<p>the issue is about interior mutability</p>



<a name="194369536"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28transparent%29/near/194369536" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html#194369536">(Apr 16 2020 at 21:25)</a>:</h4>
<p>so, you cannot transmute <code>&amp;UnsafeCell&lt;T&gt;</code> to <code>*mut T</code> <em>and write to it</em></p>



<a name="194370833"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28transparent%29/near/194370833" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html#194370833">(Apr 16 2020 at 21:39)</a>:</h4>
<p>oh, right right, <code>&amp;UnsafeCell&lt;T&gt;</code></p>
<p>Okay but is that noted anywhere outside of the docs of libcore? Perhaps we should write it down somewhere.</p>



<a name="194463642"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28transparent%29/near/194463642" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html#194463642">(Apr 17 2020 at 16:08)</a>:</h4>
<p>well it's noted in <code>UnsafeCell</code> docs</p>



<a name="194463666"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28transparent%29/near/194463666" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html#194463666">(Apr 17 2020 at 16:08)</a>:</h4>
<p>not sure which other place would fit?</p>



<a name="194465597"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28transparent%29/near/194465597" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html#194465597">(Apr 17 2020 at 16:24)</a>:</h4>
<p>FWIW I'd rather just get rid of this rule altogether. I'm pretty sure there's no good reason for it nowadays.</p>



<a name="194466306"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28transparent%29/near/194466306" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html#194466306">(Apr 17 2020 at 16:30)</a>:</h4>
<p>well, Stacked Borrows doesn't need it</p>



<a name="194466340"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28transparent%29/near/194466340" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html#194466340">(Apr 17 2020 at 16:30)</a>:</h4>
<p>but I am not sure if we are willing to commit to "whatever Stacked Borrows does" for interior mutability</p>



<a name="194467729"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28transparent%29/near/194467729" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html#194467729">(Apr 17 2020 at 16:41)</a>:</h4>
<p><code>get()</code> isn't special to the compiler either, and I can't see why we'd ever want to change that. The special casing for <code>UnsafeCell</code> that we have (e.g., whether statics are read-only memory, or whether aliasing attributes are added to LLVM IR) is all just based on "does this type contain an <code>UnsafeCell</code>".</p>



<a name="194467847"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28transparent%29/near/194467847" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html#194467847">(Apr 17 2020 at 16:42)</a>:</h4>
<p>earlier versions of stacked borrows relied on some really weird sequence of casts in <code>get</code> to make things work</p>



<a name="194467875"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28transparent%29/near/194467875" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html#194467875">(Apr 17 2020 at 16:42)</a>:</h4>
<p>so just a normal transmute from <code>&amp;UnsafeCell&lt;T&gt;</code> to <code>*mut T</code> would not have worked</p>



<a name="194467909"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28transparent%29/near/194467909" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html#194467909">(Apr 17 2020 at 16:43)</a>:</h4>
<p>current Stacked Borrows handles this better and the transmute would be fine, but who knows what final model we end up with</p>



<a name="194467997"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28transparent%29/near/194467997" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html#194467997">(Apr 17 2020 at 16:44)</a>:</h4>
<p>(the transmute is still somewhat odd as the pointer remains "tagged", so if you ever lose provenance -- such as through an integer roundtrip -- you get UB.)</p>



<a name="194468111"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28transparent%29/near/194468111" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html#194468111">(Apr 17 2020 at 16:44)</a>:</h4>
<p>so maybe <code>&amp;UnsafeCell&lt;T&gt; as *const _ as *mut T</code> is the better "non-<code>get</code>" alternative. and that is entirely equivalent to <code>get</code>  as far as latest Stacked Borrows is concerned.</p>



<a name="194468649"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28transparent%29/near/194468649" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html#194468649">(Apr 17 2020 at 16:49)</a>:</h4>
<p>Hm, I see. Then I won't push further for this change right now. But still, <code>get</code> should definitely not be magic : <code>transmute</code> may be weird around pointer provenance in general, but the obvious <code>as</code> cast really ought to work and IMO a formal model that can't make them work probably won't be satisfactory.</p>



<a name="194469374"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28transparent%29/near/194469374" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(transparent).html#194469374">(Apr 17 2020 at 16:54)</a>:</h4>
<p>I agree</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>